﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Cryptography;
using System.Text;
using System.Web.Mvc;
using System.Collections;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Drawing.Imaging;
using System.Text.RegularExpressions;
using log4net;

namespace TanWeb.Helpers
{
    public class Utils
    {
        public static string MD5Hash(string text)
        {
            MD5 md5 = new MD5CryptoServiceProvider();

            //compute hash from the bytes of text
            md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(text));

            //get hash result after compute it
            byte[] result = md5.Hash;

            StringBuilder strBuilder = new StringBuilder();
            for (int i = 0; i < result.Length; i++)
            {
                //change it into 2 hexadecimal digits
                //for each byte
                strBuilder.Append(result[i].ToString("x2"));
            }

            return strBuilder.ToString();
        }

        public static void SetSession(string key, object value)
        {
            if (key != null && !key.Equals(string.Empty))
            {
                string sessionId = System.Web.HttpContext.Current.Session.SessionID;

                if (value != null)
                {
                    RemoveSession(key);
                }

                System.Web.HttpContext.Current.Session[key + sessionId] = value;
            }
        }

        public static object GetSession(string key)
        {
            if (key != null && !key.Equals(string.Empty))
            {
                string sessionId = System.Web.HttpContext.Current.Session.SessionID;
                return System.Web.HttpContext.Current.Session[key + sessionId];
            }

            return null;
        }

        public static void RemoveSession(string key)
        {
            if (key != null && !key.Equals(string.Empty))
            {
                string sessionId = System.Web.HttpContext.Current.Session.SessionID;
                System.Web.HttpContext.Current.Session.Remove(key + sessionId);
            }
        }

        public static bool CheckLogin(ILog logger)
        {
            object loginId = GetSession(Constants.LOGIN_ID);

            bool result = loginId != null && loginId.ToString() != string.Empty;

            if (!result)
            {
                logger.Info("\tUtils: CheckLogin - Not login");
            }

            return result;
        }

        public static string SaveImage(HttpPostedFileBase file, string path)
        {
            try
            {
                string fileName = string.Empty;
                string filePath = string.Empty;

                do
                {
                    string time = DateTime.Now.ToString(Constants.FORMAT_UPLOAD_TIME);
                    fileName = file.FileName + Constants.UNDERLINE + time;
                    filePath = path + fileName;
                }
                while (File.Exists(filePath));

                System.Drawing.Image image = System.Drawing.Image.FromStream(file.InputStream);
                // Resize image to reduce size
                image = GetResizedImage(image);
                image.Save(filePath, ImageFormat.Jpeg);
                return fileName;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public static string SaveImage(System.Drawing.Image image, string path)
        {
            try
            {
                string fileName = string.Empty;
                string returnPath = string.Empty;

                do
                {
                    string time = DateTime.Now.ToString(Constants.FORMAT_UPLOAD_TIME);
                    string name = MD5Hash(time);
                    returnPath = Constants.PATH_TEMP_IMAGE + name + Constants.UNDERLINE + time + Constants.JPG_FORMAT;
                    fileName = path + name + Constants.UNDERLINE + time + Constants.JPG_FORMAT;
                }
                while (File.Exists(fileName));

                image.Save(fileName, ImageFormat.Jpeg);
                return returnPath;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public static Bitmap GetResizedImage(System.Drawing.Image image, string type = Constants.TYPE_IMAGE_NORMAL)
        {
            int width = Constants.MAX_UPLOAD_WIDTH;
            int height = Constants.MAX_UPLOAD_HEIGHT;
            double rate = 0;

            if (image.Width > image.Height)
            {
                rate = (double)width / (double)image.Width;
                height = (int)(image.Height * rate);
            }
            else
            {
                rate = (double)height / (double)image.Height;
                width = (int)(image.Width * rate);
            }

            Bitmap thumb = new Bitmap(width, height);
            Graphics gr = Graphics.FromImage(thumb);

            gr.SmoothingMode = SmoothingMode.HighQuality;
            gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
            gr.CompositingQuality = CompositingQuality.HighQuality;
            gr.SmoothingMode = SmoothingMode.None;

            gr.DrawImage(image, 0, 0, width, height);
            return thumb;
        }

        public static Bitmap GetResizedImage(string path, string type = Constants.TYPE_IMAGE_NORMAL)
        {
            if (path == null || path == string.Empty || !File.Exists(path))
            {
                return null;
            }

            System.Drawing.Image source = System.Drawing.Image.FromFile(path);
            int width = 0;

            if (type == Constants.TYPE_IMAGE_NORMAL)
            {
                width = Constants.UPLOAD_IMG_TEMP_WIDTH;
            }
            else if (type == Constants.TYPE_IMAGE_ORIGINAL)
            {
                width = source.Width;
            }
            else
            {
                width = Constants.TEMP_IMG_WIDTH;
            }

            double rate = (double)width / (double)source.Width;
            int height = (int) (source.Height * rate);

            Bitmap thumb = new Bitmap(width, height);
            Graphics gr = Graphics.FromImage(thumb);

            gr.SmoothingMode = SmoothingMode.HighQuality;
            gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
            gr.CompositingQuality = CompositingQuality.HighQuality;
            gr.SmoothingMode = SmoothingMode.None;

            gr.DrawImage(source, 0, 0, width, height);
            return thumb;
        }

        public static string GetImageUrl(System.Drawing.Image image)
        {
            if (image == null)
            {
                return string.Empty;
            }

            try
            {
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    image.Save(memoryStream, ImageFormat.Jpeg);
                    Byte[] bytes = new Byte[memoryStream.Length];
                    memoryStream.Position = 0;
                    memoryStream.Read(bytes, 0, (int)bytes.Length);
                    string base64String = Convert.ToBase64String(bytes, 0, bytes.Length);
                    return "data:image/jpg;base64," + base64String;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public static void DeleteAllImageTemp(string directoryPath, string directoryTempPath)
        {
            string path = System.Web.Hosting.HostingEnvironment.MapPath(directoryPath);
            DirectoryInfo d = new DirectoryInfo(path);
            
            TanWeb.Controllers.Business.MasterBusiness business = new Controllers.Business.MasterBusiness();
            List<TanWeb.Models.Entities.Image> lstImage = business.GetListImage(null, null, null);

            foreach (FileInfo f in d.GetFiles())
            {
                string fileName = f.Name;
                bool isDelete = true;

                foreach (TanWeb.Models.Entities.Image image in lstImage)
                {
                    if (image.ImageName == fileName)
                    {
                        isDelete = false;
                        break;
                    }
                }

                if (isDelete)
                {
                    try
                    {
                        File.Delete(f.FullName);
                    }
                    catch
                    {

                    }
                }
            }

            path = System.Web.Hosting.HostingEnvironment.MapPath(directoryTempPath);
            d = new DirectoryInfo(path);

            foreach (FileInfo f in d.GetFiles())
            {
                try
                {
                    if (f.CreationTime.AddHours(1) <= DateTime.Now)
                    {
                        File.Delete(f.FullName);
                    }
                }
                catch
                {
                }
            }
        }

        public static void DeleteUploadedImages(string directoryPath, string groupId, string subGroupId, string productId, string directoryTempPath)
        {
            string path = System.Web.Hosting.HostingEnvironment.MapPath(directoryPath);
            DirectoryInfo d = new DirectoryInfo(path);
            FileInfo[] filesInfo = d.GetFiles();

            TanWeb.Controllers.Business.MasterBusiness business = new Controllers.Business.MasterBusiness();
            List<TanWeb.Models.Entities.Image> lstImage = business.GetListImage(groupId, subGroupId, productId);

            foreach (TanWeb.Models.Entities.Image image in lstImage)
            {
                foreach (FileInfo f in filesInfo)
                {
                    try
                    {
                        if (f.Name == image.ImageName)
                        {
                            File.Delete(f.FullName);
                            break;
                        }
                    }
                    catch
                    {
                    }
                }
            }

            ArrayList fileNameList = (ArrayList)Utils.GetSession(Constants.SESSION_UPLOADED_FILENAME);

            foreach (TanWeb.Models.Entities.UploadedFile file in fileNameList)
            {
                foreach (FileInfo f in filesInfo)
                {
                    try
                    {
                        if (f.Name == file.fileName)
                        {
                            File.Delete(f.FullName);
                            break;
                        }
                    }
                    catch
                    {
                    }
                }
            }
        }
    }
}